#ifndef __HEAD_H__
#define __HEAD_H__

#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <stdbool.h>
#include "../utils/cJSON.h"
#include "../utils/vec.h"

#define CARD_NUMBER 54
#define CARD_CNT 13

typedef enum {
    SPADE,
    HEART,
    CLUB,
    DIAMOND,
    JOCKER,
} CARD_SUIT;

typedef enum {
    CARD_SPADE_3,
    CARD_SPADE_4,
    CARD_SPADE_5,
    CARD_SPADE_6,
    CARD_SPADE_7,
    CARD_SPADE_8,
    CARD_SPADE_9,
    CARD_SPADE_10,
    CARD_SPADE_J,
    CARD_SPADE_Q,
    CARD_SPADE_K,
    CARD_SPADE_A,
    CARD_SPADE_2,
    CARD_HEART_3,
    CARD_HEART_4,
    CARD_HEART_5,
    CARD_HEART_6,
    CARD_HEART_7,
    CARD_HEART_8,
    CARD_HEART_9,
    CARD_HEART_10,
    CARD_HEART_J,
    CARD_HEART_Q,
    CARD_HEART_K,
    CARD_HEART_A,
    CARD_HEART_2,
    CARD_CLUB_3,
    CARD_CLUB_4,
    CARD_CLUB_5,
    CARD_CLUB_6,
    CARD_CLUB_7,
    CARD_CLUB_8,
    CARD_CLUB_9,
    CARD_CLUB_10,
    CARD_CLUB_J,
    CARD_CLUB_Q,
    CARD_CLUB_K,
    CARD_CLUB_A,
    CARD_CLUB_2,
    CARD_DIAMOND_3,
    CARD_DIAMOND_4,
    CARD_DIAMOND_5,
    CARD_DIAMOND_6,
    CARD_DIAMOND_7,
    CARD_DIAMOND_8,
    CARD_DIAMOND_9,
    CARD_DIAMOND_10,
    CARD_DIAMOND_J,
    CARD_DIAMOND_Q,
    CARD_DIAMOND_K,
    CARD_DIAMOND_A,
    CARD_DIAMOND_2,
    CARD_BLACK_JOCKER,
    CARD_RED_JOCKER,
} CARD;

#define CARD_FLOWER(card) (CARD_SUIT)((card) / CARD_CNT)

#define CARD_VALUE(card) ((card) % CARD_CNT)

#define CARD_IS_JOCKER(card) ((card) == CARD_BLACK_JOCKER || (card) == CARD_RED_JOCKER)

/**
 * @brief 牌型
 * @enum SINGLE 单牌
 * @enum PAIR 对子
 * @enum STRAIGHT 顺子
 * @enum DOUBLE_SEQUENCE 连对
 * @enum THREE 三条
 * @enum THREE_WITH_ONE 三带一
 * @enum BOMB 炸弹
 * @enum ROCKET 火箭
 * @enum INVALID_TYPE 无效牌型
 */
typedef enum {
    SINGLE,
    PAIR,
    STRAIGHT,
    DOUBLE_SEQUENCE,
    THREE,
    THREE_WITH_ONE,
    THREE_WITH_PAIR,
    FOUR_WITH_PAIR,
    BOMB,
    JOCKER_BOMB,
    ROCKET,
    ROCKET_WITH_SINGLE,
    ROCKET_WITH_PAIR,
    INVALID_TYPE
} HAND_TYPE;

// 牌型判断函数
HAND_TYPE get_card_type(CARD* cards, size_t len);
bool compare_cards(CARD* prev_cards, size_t prev_len, CARD* new_cards, size_t new_len);

/**
 * 玩家状态
 * @param none 未准备
 * @param ready 准备
 * @param gameing 游戏中
 */
typedef enum {
	PLAYER_STATUS_NONE,
	PLAYER_STATUS_READY,
	PLAYER_STATUS_GAMEING,
} PLAYER_STATUS;

typedef struct {
    int id;
    char* username;
    PLAYER_STATUS status;
    Vec(CARD) handcard;
} player_t; // 玩家

/**
 * 游戏状态
 * @param init 初始化, 随后进行洗牌，发牌
 * @param start 开始，首先出牌的玩家任意出牌
 * @param gameing 游戏中
 * @param end 结束
 * @param wait_player 等待玩家
*/
typedef enum {
	GAME_STATUS_INIT,
	GAME_STATUS_START,
    GAME_STATUS_CALLLOAD,
    GAME_STATUS_ROBLOAD,
	GAME_STATUS_GAMEING,
	GAME_STATUS_END,
	GAME_STATUS_WAIT_PLAYER,
} GAME_STATUS;

typedef enum {
    ROB_LOAD_NONE,
    ROB_LOAD_CALL,
    ROB_LOAD_ROB,
    ROB_LOAD_PASS,
}ROB_LOAD_STATUS;


/**
 * 游戏信息
 * @param id 游戏房间id
 * @param load_id 游戏房主id
 * @param status 游戏状态
 * @param players 玩家信息
 * @param player_count 玩家数量
 * @param who 当前出牌玩家
 * @param count 当前局数
 * @param cards 上家手牌
 */
typedef struct {
	int id;
    char* room_name;
    pthread_cond_t cond;
    pthread_mutex_t mutex;
    GAME_STATUS status;
    player_t players[3];
    int player_count;
    int who;
    int last_who;
    int who_load;
    short rob_status[3];
    int count;
    Vec(CARD) cards;
} game_t; // 游戏信息

/*--------------------------------*/
/**
 * 游戏初始化
 * @return 返回游戏对象
 */
game_t* game_init(int id, char* room_name);

/**
 * 游戏销毁
 * @param game 游戏对象
*/
void game_destory(game_t *game);

char *game_play_card(game_t *game, player_t *player, CARD *card, int cardsize);

void* game_thread_func(void* arg);

cJSON* game_to_json(game_t *game);

#endif